home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2005 March / Macworld CD March 2005 - Marathon Trilogy.iso / Shareware World / User Interface / RocketLauncher.sit / RocketLauncher / RocketLauncher.CVS / AppInfo.m,v < prev    next >
Encoding:
Text File  |  2005-01-09  |  4.7 KB  |  196 lines

  1. head     1.1;
  2. branch   1.1.1;
  3. access   ;
  4. symbols  start:1.1.1.1 oleg:1.1.1;
  5. locks    ; strict;
  6. comment  @// @;
  7.  
  8.  
  9. 1.1
  10. date     2005.01.09.18.45.06;  author oleg;  state Exp;
  11. branches 1.1.1.1;
  12. next     ;
  13.  
  14. 1.1.1.1
  15. date     2005.01.09.18.45.06;  author oleg;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19.  
  20. desc
  21. @@
  22.  
  23.  
  24.  
  25. 1.1
  26. log
  27. @Initial revision
  28. @
  29. text
  30. @//
  31. //  AppInfo.m
  32. //  RocketLauncher
  33. //
  34. //  Created by Oleg Kibirev on 12/31/04.
  35. //  Copyright 2004 My Stuff. All rights reserved.
  36. //
  37.  
  38. #import "AppInfo.h"
  39. #import <unistd.h>
  40. #import <sys/stat.h>
  41.  
  42.  
  43. @@implementation AppInfo
  44.  
  45. -(NSString *)fullPath {
  46.     return [[NSWorkspace sharedWorkspace] fullPathForApplication:name];
  47. }
  48.  
  49. -(id)initWithName: (NSString *)n path: (NSString *)p isOSX: (BOOL)osx {
  50.     self = [super init];
  51.     name = [n retain];
  52.     path = [p retain];
  53.     isOSX = osx;
  54.     return self;
  55. }
  56.  
  57. -(void)copyFrom: (AppInfo *)ai {
  58.     [name autorelease]; name = [ai->name retain];
  59.     [path autorelease]; path = [ai->path retain];
  60.     [icon autorelease]; icon = [ai->icon retain];
  61.     isOSX = ai->isOSX;
  62.     gotIcon = ai->gotIcon;
  63. }
  64.  
  65. -(void)dealloc {
  66.     [name release];
  67.     [icon release];
  68.     [path release];
  69.     [super dealloc];
  70. }
  71.  
  72. -(NSString *)name { return name; }
  73. -(NSImage *)icon {
  74.     if (!gotIcon) {
  75.         icon = [[[NSWorkspace sharedWorkspace] iconForFile:path] retain];
  76.         gotIcon = YES;
  77.     }
  78.     return icon;
  79. }
  80.  
  81. -(NSComparisonResult)compare: (AppInfo *)ai {
  82.     return [name compare: [ai name]];
  83. }
  84.  
  85. -(BOOL)launch {
  86.     NSWorkspace *ws = [NSWorkspace sharedWorkspace];
  87.     return  [ws launchApplication:path] || [ws launchApplication:name];
  88. }
  89.  
  90. static char *clgets(char *buf, size_t len, FILE *fin) {
  91.     buf[len-1] = '\0';
  92.     if (!fgets(buf, len-1, fin)) return NULL;
  93.     len = strlen(buf);
  94.     if (len && buf[len-1] == '\n')
  95.         buf[len-1] = '\0';
  96.     return buf;
  97. }
  98.  
  99. BOOL hasSubstr(const char *s1, const char *s2) {
  100.     NSRange r = [[NSString stringWithUTF8String:s1] rangeOfString:[NSString stringWithUTF8String:s2] options: NSCaseInsensitiveSearch];
  101.     return r.location != NSNotFound;
  102. }
  103.  
  104. +(NSArray *)allApps: (NSArray *)oldList {
  105.     NSMutableArray *ma = [NSMutableArray arrayWithCapacity:100];
  106.     // Is there a programmatic way to do this?
  107.     FILE *appList = popen("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -dump", "r");
  108.     char buf[4096];
  109.     NSMutableDictionary *oldApps = [NSMutableDictionary dictionaryWithCapacity:100];
  110.     if (oldList != nil) {
  111.         int i;
  112.         for (i = 0; i < [oldList count]; i++) {
  113.             AppInfo *ai = [oldList objectAtIndex:i];
  114.             [oldApps setObject:ai forKey:[ai name]];
  115.         }
  116.     }
  117.     if (appList) {
  118.         NSMutableDictionary *appSet = [NSMutableDictionary dictionaryWithCapacity:100];
  119.         while (clgets(buf, sizeof(buf), appList)) {
  120.             if (buf[0] != 'B') continue;
  121. mainLoop:;
  122.             size_t end = strlen(buf)-1;
  123.             if (end >= 4 && !strcasecmp(buf+end-3, ".app")) {
  124.                 end-=4;
  125.                 buf[end+1] = '\0';
  126.             }
  127.             while (end >= 2 && (buf[end-1] != ' ' || buf[end-2] != ' '))
  128.                 end--;
  129.             if (end < 2) continue;
  130.             NSString *appName = [NSString stringWithUTF8String:buf+end];
  131.             NSString *appPath = nil;
  132.             if (!appName) continue;
  133.             if ([appName isEqual: @@"RocketLauncher"]) continue;
  134.             int lineNo;
  135.             BOOL osx;
  136.             for (lineNo = 0; lineNo < 10 && clgets(buf, sizeof(buf), appList); lineNo++) {
  137.                 char *p = buf;
  138.                 while (*p && isspace(*p)) p++;
  139.                 if (p[0] == 'B') goto mainLoop;
  140.                 if (*p == 'V' && isdigit(p[1])) {
  141.                     while (!isspace(*p)) p++;
  142.                     while (*p && isspace(*p)) p++;
  143.                     // Filter out system apps
  144.                     if (!strncasecmp(p, "/System/", sizeof("/System/")-1))
  145.                         continue;
  146.                     if (hasSubstr(p, "/System Folder/"))
  147.                         continue;
  148. #if 0
  149.                     if (hasSubstr(p, "/Applications (Mac OS 9)/"))
  150.                         continue;
  151. #endif
  152.                     if (hasSubstr(p, ".exe ")) // Virtual PC wrappers
  153.                         continue; 
  154.                     struct stat st;
  155.                     if (stat(p, &st) == -1)
  156.                         continue;
  157.                     if(S_ISDIR(st.st_mode)) {
  158.                         // Check if a valid bundle
  159.                         NSString *p1 = [[[NSString stringWithUTF8String:p] stringByAppendingPathComponent:@@"Contents"] stringByAppendingPathComponent: @@"Info.plist"];
  160.                         if (access([p1 UTF8String], R_OK) == -1)
  161.                             continue;
  162.                         osx = YES;
  163.                     } else
  164.                         osx = NO;
  165.                     appPath = [NSString stringWithUTF8String:p];
  166.                     break;
  167.                 }
  168.             }
  169.             if (!appPath) continue;
  170.             AppInfo *ai = [appSet objectForKey:appName];
  171.             AppInfo *nai = [[[AppInfo alloc] initWithName:appName path:appPath isOSX: osx] autorelease];
  172.             AppInfo *oldAI = [oldApps objectForKey:appName];
  173.             if (oldAI && [oldAI->path isEqual:nai->path] && oldAI->icon && !nai->icon)
  174.                 nai = oldAI;
  175.             if (!ai) {
  176.                 [appSet setObject:nai forKey:appName];
  177.                 [ma addObject:nai];
  178.             } else if (([ai icon] == nil && [nai icon] != nil) || (nai->isOSX && !ai->isOSX))
  179.                 [ai copyFrom:nai];
  180.         }
  181.         pclose(appList);
  182.     }
  183.     [ma sortUsingSelector:@@selector(compare:)];
  184.     return ma;
  185. }
  186. @@end
  187. @
  188.  
  189.  
  190. 1.1.1.1
  191. log
  192. @RocketLauncher
  193. @
  194. text
  195. @@
  196.